﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using Subfaculty.WebApplication.ViewModels;
using Subfaculty.Common.Entities;

namespace Subfaculty.WebApplication.Translators
{
    internal class StudyLoadItemTranslator
    {
        public IEnumerable<StudyLoadItemViewModel> MakeItems(ICollection<StudyLoadItem> sourceItems, StudyYear year)
        {
            var groups = from item in sourceItems
                         group item by item.AllocationItem;

            foreach (var group in groups)
            {
                yield return MakeItem(group.AsEnumerable<StudyLoadItem>(), group.Key, year);
            }
        }

        protected StudyLoadItemViewModel MakeItem(IEnumerable<StudyLoadItem> slItems, AllocationItem allocItem, StudyYear year)
        {
            StudyLoadItemViewModel slViewItem = new StudyLoadItemViewModel();
            //slViewItemList.Add(slViewItem);

            //AllocationItem allocItem = slItemGroup.Key;
            slViewItem.KoofSRS = GetKoefSRS(allocItem, year);
            slViewItem.Semester = allocItem.Semester;
            slViewItem.CountGroup = CountGroup(allocItem, year);
            slViewItem.CountStudent = CountStudents(allocItem, year);
            slViewItem.CountSubGroup = CountSudGrop(allocItem, year);
            slViewItem.TypeSRS = GetTypeSRS(allocItem);
            slViewItem.GroupList = GetGroups(allocItem, year);
            slViewItem.Discipline = allocItem.Discipline.Title;

            foreach (var slItem in slItems)
            {
                slViewItem.AllHours += slItem.Hours;

                switch (slItem.TypeLoadItem)
                {
                    case ETypeLoadItem.LectureStudy:
                        slViewItem.HoursLecture = slItem.Hours;
                        slViewItem.AuditorHoursPlan += slItem.Hours;
                        break;
                    case ETypeLoadItem.PracticeStudy:
                        slViewItem.HoursPracticePlan = allocItem.HoursLab;
                        slViewItem.HoursPracticeAll = slItem.Hours;
                        slViewItem.AuditorHoursPlan += slItem.Hours;
                        break;
                    case ETypeLoadItem.LabworkStudy:
                        slViewItem.HoursLabPlan = allocItem.HoursLab;
                        slViewItem.HoursLabAll = slItem.Hours;
                        slViewItem.AuditorHoursPlan += slItem.Hours;
                        break;
                    case ETypeLoadItem.SRSForFullTimeLearning:
                        slViewItem.SRSHoursPlan = allocItem.HoursLab;
                        slViewItem.SRSHours = slItem.Hours;
                        break;

                    case ETypeLoadItem.ConsultationForDistanceLearning:
                        slViewItem.ConsultationDistanseHours = slItem.Hours;
                        break;
                    case ETypeLoadItem.ConsultationForEveningLearning:
                        slViewItem.ConsultationEveningHours = slItem.Hours;
                        break;
                    case ETypeLoadItem.ConsultationForFullTimeLearning:
                        slViewItem.ConsultationFullTimeHours = slItem.Hours;
                        break;

                    case ETypeLoadItem.ConsultationForExam:
                        slViewItem.ConsultationExamHours = slItem.Hours;
                        break;

                    case ETypeLoadItem.ControlWorkForDistanceLearning:
                        slViewItem.ControlWorkDistanseHours = slItem.Hours;
                        break;

                    case ETypeLoadItem.ControlWorkForEveningLearning:
                        slViewItem.ControlWorkEveningHours = slItem.Hours;
                        break;

                    case ETypeLoadItem.CourseProjectForDistanceLearning:
                        slViewItem.CourseWorkEveningDistanseHours = slItem.Hours;
                        break;

                    case ETypeLoadItem.Exam:
                    case ETypeLoadItem.ExamGOS:
                        slViewItem.ExamHours += slItem.Hours;
                        break;

                    case ETypeLoadItem.Test:
                        slViewItem.TestHours = slViewItem.TestHours;
                        break;

                    case ETypeLoadItem.Raiting:
                        slViewItem.RatingHours = slViewItem.RatingHours;
                        break;
                }
            }
            return slViewItem;
        }

        #region статические выборки
        private double GetKoefSRS(AllocationItem allocItem, StudyYear year)
        {
            double c = allocItem.HoursSRS > 110 ? 110 : allocItem.HoursSRS;
            double k = CountStudents(allocItem, year);

            switch (allocItem.ETypeSRS)
            {
                case ETypeSRS.Semesterwork:
                    if (allocItem.Discipline.Title.Equals("иностранный язык"))
                        return k * 1.8;
                    else if (allocItem.Discipline.Title == "инженерная графика"
                             || allocItem.Discipline.Title == "начертательная геометрия")
                        return k * 1.2;
                    return k * 0.7;
                case ETypeSRS.Coursework:
                    return k * 3.0;
                case ETypeSRS.Project:
                    return k * 0.4;
                default:
                    throw new Exception("Нет подходящего выбора для правила SRSForFullTimeLearningRule");
            }
        }

        private bool IsCurrentYearGroup(StudyGroupState state, StudyGroup group, AllocationItem allocItem, StudyYear year)
        {
            return state.Semester == (year.StartDate - group.StartStudyYear.StartDate) * 2 + allocItem.Semester
                                     && state.GroupState == EGroupState.Active;
        }

        private int CountSudGrop(AllocationItem allocItem, StudyYear year)
        {
            return (from studyGroup in allocItem.StudyGroups
                    select
                        (from state in studyGroup.StudyGroupStates
                         where IsCurrentYearGroup(state, studyGroup, allocItem, year)
                         select state.CountSubgroup).Sum())
                        .Sum();
        }

        private int CountGroup(AllocationItem allocItem, StudyYear year)
        {
            return (from studyGroup in allocItem.StudyGroups
                    select
                         (from state in studyGroup.StudyGroupStates
                          where IsCurrentYearGroup(state, studyGroup, allocItem, year)
                          select state).Count())
                         .Sum();
        }

        private int CountStudents(AllocationItem allocItem, StudyYear year)
        {
            return (from studyGroup in allocItem.StudyGroups
                    select
                        (from state in studyGroup.StudyGroupStates
                         where IsCurrentYearGroup(state, studyGroup, allocItem, year)
                         select state.CountStudent).Sum())
                         .Sum();
        }

        private string GetTypeSRS(AllocationItem allocItem)
        {
            switch (allocItem.ETypeSRS)
            {
                case ETypeSRS.Coursework: return "Курсовая работа";
                case ETypeSRS.Project: return "Курсовой проект";
                case ETypeSRS.Semesterwork: return "Семестровая работа";
                case ETypeSRS.Report: return "Реферат";
                default: return "Нет";
            }
        }

        private string GetGroups(AllocationItem allocItem, StudyYear year)
        {
            return String.Join(",", (from studyGroup in allocItem.StudyGroups
                                     select
                                         String.Join(",", (from state in studyGroup.StudyGroupStates
                                                           where IsCurrentYearGroup(state, studyGroup, allocItem, year)
                                                           select state.Name).ToArray())));

        }
        #endregion
    }
}